﻿using System;

namespace Sustainalytics.Portfolios.BL
{
    using Newtonsoft.Json;
    using Sustainalytics.DataLayer.Shared;
    using Sustainalytics.Entities;
    using Sustainalytics.Portfolios.BL.Exceptions;
    using Sustainalytics.Portfolios.BL.Validators;
    using Sustainalytics.Replication.Publisher;
    using Sustainalytics.Utils;
    using System.Collections.Generic;

    public interface IPortfolioRenameHandler
    {
        void UpdatePortfolioName(Guid id, string newName, PortfolioUserClaims userClaims);
    }

    public class PortfolioRenameHandler : IPortfolioRenameHandler
    {
        private readonly IRepositoryCollection<Portfolio> _portfolioRepository;
        private readonly IRepositoryCollection<Portfolio> _systemPortfolioRepository;
        private readonly ServiceBusPublisher _serviceBusPublisher;

        public PortfolioRenameHandler(
            PortfolioTypeCollection<Portfolio> portfolioCollection,
            ServiceBusPublisher serviceBusPublisher)
        {
            this._portfolioRepository = portfolioCollection.ClientCollection;
            this._systemPortfolioRepository = portfolioCollection.SystemCollections;
            this._serviceBusPublisher = serviceBusPublisher;
        }

        public void UpdatePortfolioName(Guid id, string newName, PortfolioUserClaims userClaims)
        {
            if (string.IsNullOrEmpty(newName))
            {
                throw new PortfolioNameNullException();
            }

            Portfolio portfolio;
            IRepositoryCollection<Portfolio> repository;
            bool isSystemPortfolio = false;
            if ((portfolio = this._portfolioRepository.Read(id)) != null)
            {
                repository = this._portfolioRepository;
            }
            else
            {
                portfolio = this._systemPortfolioRepository.Read(id);
                repository = this._systemPortfolioRepository;
                isSystemPortfolio = true;
            }

            if (!PortfolioValidator.Write().IsValid(portfolio, userClaims))
            {
                throw new PortfolioModificationUnauthorizedException();
            }

            if (!PortfolioValidator.NameValidator(this._portfolioRepository, userClaims).IsValid(portfolio, newName))
            {
                throw new PortfolioNameAlreadyExists();
            }

            if (!PortfolioValidator.NameValidator(this._systemPortfolioRepository, userClaims).IsValid(portfolio, newName))
            {
                throw new PortfolioNameAlreadyExists();
            }

            portfolio.Name = newName;
            portfolio.DateModified = DateTime.Today;
            repository.CreateOrUpdate(portfolio);
            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(portfolio),
                ReplicationUtils.EntityType.Portfolio,
                ReplicationUtils.Operation.CreateOrUpdate,
                isSystemPortfolio ? ReplicationUtils.ConnectionStringType.ClientDW : ReplicationUtils.ConnectionStringType.ClientPlatform);
        }
    }
}
